package com.tianji.remark.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.tianji.common.autoconfigure.mq.RabbitMqHelper;
import com.tianji.common.exceptions.BadRequestException;
import com.tianji.common.utils.*;
import com.tianji.remark.domain.dto.LikeRecordFormDTO;
import com.tianji.api.dto.remark.LikedTimesDTO;
import com.tianji.remark.domain.po.LikedRecord;
import com.tianji.remark.mapper.LikedRecordMapper;
import com.tianji.remark.service.ILikedRecordService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import static com.tianji.common.constants.MqConstants.Exchange.LIKE_RECORD_EXCHANGE;
import static com.tianji.common.constants.MqConstants.Key.LIKED_TIMES_KEY_TEMPLATE;

/**
 * <p>
 * 点赞记录表 服务实现类
 * </p>
 *
 * @author fx
 * @since 2024-08-27
 */
//@Service
@RequiredArgsConstructor
public class LikedRecordServiceImpl extends ServiceImpl<LikedRecordMapper, LikedRecord> implements ILikedRecordService {

    private final RabbitMqHelper mqHelper;

    /**
     * 01 点赞或者取消点赞（day06-随堂-01）
     *
     * @param formDTO
     */
    @Override
    public void LikeOrUnlike(LikeRecordFormDTO formDTO) {
        // 0 参数校验
        if (ObjectUtils.isEmpty(formDTO.getBizType())) {
            throw new BadRequestException("业务类型不能为空");
        }
        // 1 判断是 点赞 还是 取消点赞
        Boolean isSuccessed = formDTO.getLiked() ? addLikedRecord(formDTO) : deleteLikedRecord(formDTO);

        // 2 操作成功，统计点赞记录 mq通知业务方
        if (BooleanUtils.isTrue(isSuccessed)) {
            // 2.1 统计点赞数
            Integer likeTimes = this.lambdaQuery().eq(LikedRecord::getBizId, formDTO.getBizId()).count();
            // 2.2 mq通知业务方
            mqHelper.send(LIKE_RECORD_EXCHANGE
                    , StringUtils.format(LIKED_TIMES_KEY_TEMPLATE, formDTO.getBizType()),
                    LikedTimesDTO.of(formDTO.getBizId(), likeTimes));
        }
    }

    /**
     * 02 根据业务id集合查询点赞状态（day06-随堂-02）
     * 查询当前用户是否已经点赞
     *
     * @param bizIds
     * @return
     */
    @Override
    public Set<Long> isliked(List<Long> bizIds) {
        // 1 根据传入的业务id集合，查询有当前用户的记录的id的集合
        List<LikedRecord> list = this.lambdaQuery()
                .select(LikedRecord::getBizId)
                .eq(LikedRecord::getUserId, UserContext.getUser())
                .in(LikedRecord::getBizId, bizIds)
                .list();
        // 2 返回对应的id集合
        return list.stream().map(LikedRecord::getBizId).collect(Collectors.toSet());
    }

    /**
     * 03 统计点赞次数，并发送消息，用于持久化点赞次数（day06-随堂-03）
     *
     * @param bizType
     * @param maxBizSize
     */
    @Override
    public void readLikedTimesAndSendMessage(String bizType, Integer maxBizSize) {

    }

    /**
     * tool-01 点赞 新增点赞记录
     *
     * @param formDTO
     * @return
     */
    private Boolean addLikedRecord(LikeRecordFormDTO formDTO) {
        // 0 检验点赞记录是否存在
        Integer count = this.lambdaQuery()
                .eq(LikedRecord::getBizId, formDTO.getBizId())
                .eq(LikedRecord::getUserId, UserContext.getUser()).count();
        if (count > 0) return false; // 点赞记录存在，直接返回

        // 1 dto转po ，设置userId
       /* LikedRecord likedRecord = BeanUtils.copyBean(formDTO, LikedRecord.class);
        likedRecord.setUserId(UserContext.getUser());*/
        LikedRecord likedRecord = new LikedRecord()
                .setBizId(formDTO.getBizId())
                .setBizType(formDTO.getBizType())
                .setUserId(UserContext.getUser());
        // 2 添加点赞记录到数据库
        // 3 根据保存情况返回
        return this.save(likedRecord);
    }

    /**
     * tool-02 取消点赞 删除点赞记录
     *
     * @param formDTO
     * @return
     */
    private Boolean deleteLikedRecord(LikeRecordFormDTO formDTO) {
        // 1 刹车农户点赞记录
        // 2 根据删除结果返回
        return this.remove(new LambdaQueryWrapper<LikedRecord>()
                .eq(LikedRecord::getBizId, formDTO.getBizId())
                .eq(LikedRecord::getUserId, UserContext.getUser()));
    }
}

























